#include "../include/SmartHomeMonitorServer.h"
#include "../include/Logger.h"
#include "../include/UserSignupSection1.h"
#include "../include/UserSignupSection2.h"
#include "../include/UserLoginSection1.h"
#include "../include/UserLoginSection2.h"
#include "../include/Packet.h"

SmartHomeMonitorServer::SmartHomeMonitorServer(size_t threadNum, size_t queueSize, unsigned short port, const string &ip, 
                                               const string &host, const string &user, const string &password, 
                                               const string &database, unsigned short mysqlPort): _threadPool(threadNum, queueSize), _tcpServer(port, ip), _mysqlClient() {
    using namespace std::placeholders;
    _tcpServer.setAllCallbacks(std::bind(&SmartHomeMonitorServer::onNewConnection, this, _1), std::bind(&SmartHomeMonitorServer::onMessage, this, _1), std::bind(&SmartHomeMonitorServer::onClose, this, _1));
    _mysqlClient.connect(host, user, password, database, mysqlPort);
}

void SmartHomeMonitorServer::start() {
    _threadPool.start();
    _tcpServer.start();
}

void SmartHomeMonitorServer::stop() {
    _tcpServer.stop();
    _threadPool.stop();
}

void SmartHomeMonitorServer::onNewConnection(shared_ptr<TcpConnection> pTcpConnection) {
    moqi::LOG_INFO("%s connected.", pTcpConnection->getConnectionInfo().c_str());
}

void SmartHomeMonitorServer::onMessage(shared_ptr<TcpConnection> pTcpConnection) {
    Packet packet;
    pTcpConnection->readPacket(packet);
    moqi::LOG_DEBUG("type: %d, len: %d, msg: %s", packet._type, packet._length, packet._msg.c_str());
    if (packet._type == TASK_SIGNUP_SECTION1) {
        _threadPool.addTask(std::bind(&UserSignupSection1::process, UserSignupSection1(packet, pTcpConnection, std::ref(_mysqlClient))));
    }
    if (packet._type == TASK_SIGNUP_SECTION2) {
        _threadPool.addTask(std::bind(&UserSignupSection2::process, UserSignupSection2(packet, pTcpConnection, std::ref(_mysqlClient))));
    }
    if (packet._type == TASK_LOGIN_SECTION1) {
        _threadPool.addTask(std::bind(&UserLoginSection1::process, UserLoginSection1(packet, pTcpConnection, std::ref(_mysqlClient))));
    }
    if (packet._type == TASK_LOGIN_SECTION2) {
        _threadPool.addTask(std::bind(&UserLoginSection2::process, UserLoginSection2(packet, pTcpConnection, std::ref(_mysqlClient))));
    }
}

void SmartHomeMonitorServer::onClose(shared_ptr<TcpConnection> pTcpConnection) {
    moqi::LOG_INFO("%s disconnected.", pTcpConnection->getConnectionInfo().c_str());
}
